import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';

/// 表示资源管理器（Explorer）的持久化 UI 状态。
///
/// - [expanded]：当前展开的目录路径集合；
/// - [selectedPath]：当前选中的节点路径；
/// - [scrollOffset]：滚动条位置，用于恢复上次浏览位置。
class ExplorerPersistedState {
  /// 已展开的目录路径集合。
  final Set<String> expanded;

  /// 当前选中的路径（可能为文件或文件夹）。
  final String? selectedPath;

  /// 滚动偏移量，用于恢复滚动条位置。
  final double scrollOffset;

  ExplorerPersistedState({
    required this.expanded,
    required this.selectedPath,
    required this.scrollOffset,
  });

  /// 转换为 Map（便于序列化存储）。
  Map<String, dynamic> toMap() => {
    'expanded': expanded.toList(),
    'selectedPath': selectedPath,
    'scrollOffset': scrollOffset,
  };

  /// 从 Map 反序列化恢复状态。
  factory ExplorerPersistedState.fromMap(Map<String, dynamic> map) {
    final exp = (map['expanded'] as List?)?.cast<String>() ?? const <String>[];
    final sp = map['selectedPath'];
    final so = map['scrollOffset'];
    return ExplorerPersistedState(
      expanded: {...exp},
      selectedPath: sp is String ? sp : null,
      scrollOffset: so is num ? so.toDouble() : 0.0,
    );
  }
}

/// 封装资源管理器状态的持久化逻辑。
///
/// 基于 [SharedPreferences] 存储不同工程下的资源管理器 UI 状态，
/// 可以区分不同项目的展开 / 选中 / 滚动信息。
class ExplorerPersistence {
  /// 建议用“工程根名拼接”或真实路径的哈希作为 [scope]，确保不同工程状态互不干扰。
  final String scope;

  ExplorerPersistence(this.scope);

  /// 存储 key 格式：`explorer_state@{scope}`
  String get _key => 'explorer_state@$scope';

  /// 保存状态到本地存储。
  Future<void> save(ExplorerPersistedState state) async {
    final sp = await SharedPreferences.getInstance();
    await sp.setString(_key, jsonEncode(state.toMap()));
  }

  /// 加载状态；如果数据损坏或不存在，则返回 `null`。
  Future<ExplorerPersistedState?> load() async {
    final sp = await SharedPreferences.getInstance();
    final raw = sp.getString(_key);
    if (raw == null) return null;
    try {
      return ExplorerPersistedState.fromMap(
        jsonDecode(raw) as Map<String, dynamic>,
      );
    } catch (_) {
      return null;
    }
  }

  /// 清除当前工程的持久化状态。
  Future<void> clear() async {
    final sp = await SharedPreferences.getInstance();
    await sp.remove(_key);
  }
}
